grammar cmm;

prog
    : statement+
    ;

writeStatement
    : Write '(' conditionalExpression ')' ';'
    ;

primaryExpression
    :   Identifier
    |   Constant
    |   Zero
    |   True
    |   False
    |   StringLiteral
    |   '(' expression ')'
    ;

postfixExpression
    :   primaryExpression
    |   postfixExpression '[' Constant ']'
    |   postfixExpression '[' Zero ']'
    |   postfixExpression '[' expression ']'
    |   postfixExpression '(' argumentExpressionList? ')'
//    |   postfixExpression '.' Identifier
    |   postfixExpression '++'
    |   postfixExpression '--'
    ;

argumentExpressionList
    :   assignmentExpression
    |   argumentExpressionList ',' assignmentExpression
    |   argumentExpressionList ',' (Identifier|Constant|True|False)
    ;

unaryExpression
    :   postfixExpression
    |   '++' unaryExpression
    |   '--' unaryExpression
    |   unaryOperator castExpression
    |   'sizeof' unaryExpression
    |   'sizeof' '(' typeName ')'
    ;

multiplicativeExpression
    :   castExpression
    |   multiplicativeExpression '*' castExpression
    |   multiplicativeExpression '/' castExpression
    |   multiplicativeExpression '%' castExpression
    ;

castExpression
    :   unaryExpression
    |   '(' typeName ')' castExpression
    ;

additiveExpression
    :   multiplicativeExpression
    |   additiveExpression '+' multiplicativeExpression
    |   additiveExpression '-' multiplicativeExpression
    ;

shiftExpression
    :   additiveExpression
    |   shiftExpression '<<' additiveExpression
    |   shiftExpression '>>' additiveExpression
    ;

relationalExpression
    :   shiftExpression
    |   relationalExpression '<' shiftExpression
    |   relationalExpression '>' shiftExpression
    |   relationalExpression '<=' shiftExpression
    |   relationalExpression '>=' shiftExpression
    ;

equalityExpression
    :   relationalExpression
    |   equalityExpression '==' relationalExpression
    |   equalityExpression '!=' relationalExpression
    ;

andExpression
    :   equalityExpression
    |   andExpression '&' equalityExpression
    ;

exclusiveOrExpression
    :   andExpression
    |   exclusiveOrExpression '^' andExpression
    ;

inclusiveOrExpression
    :   exclusiveOrExpression
    |   inclusiveOrExpression '|' exclusiveOrExpression
    ;

logicalAndExpression
    :   inclusiveOrExpression
    |   logicalAndExpression '&&' inclusiveOrExpression
    ;

logicalOrExpression
    :   logicalAndExpression
    |   logicalOrExpression '||' logicalAndExpression
    ;

conditionalExpression
    :   logicalOrExpression ('?' expression ':' expression)?
    ;

assignmentExpression
    :   unaryExpression assignmentOperator conditionalExpression
    //|   conditionalExpression
    ;


constantExpression
    :   conditionalExpression
    ;

assignmentOperator
    :   '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='
    ;

unaryOperator
    :   '&' | '*' | '+' | '-' | '~' | '!'
    ;

declaration
    :   declarationSpecifier initDeclaratorList? ';'
    ;

declarationSpecifier
    :   'char'
    |   'short'
    |   'int'
    |   'long'
    |   'float'
    |   'double'
    ;

initDeclaratorList
    :   initDeclarator
    |   initDeclaratorList ',' initDeclarator
    ;

declarator
    :   directDeclarator
    ;

directDeclarator
    :   Identifier ('(' parameterList ')')?
    //|   '(' declarator ')'
    //|   directDeclarator '[' conditionalExpression? ']'
    |   directDeclarator '[' constantExpression ']'
    //|   Identifier '(' parameterList ')'
    //|   Identifier '(' identifierList? ')'
    ;

identifierList
    :   Identifier
    |   identifierList ',' Identifier
    ;

parameterList
    :   parameterDeclaration
    |   parameterList ',' parameterDeclaration
    ;

parameterDeclaration
    :   declarationSpecifier declarator
    ;

initDeclarator
    :   declarator
    |   declarator '=' initializer
    ;

initializer
    :   conditionalExpression
    |   '{' initializerList '}'
    ;

//designation? initializer
initializerList
    :   conditionalExpression
    |   initializerList ','  conditionalExpression
    ;

//designation
//    :   designatorList '='
//    ;

//designatorList
//    :   designator
//    |   designatorList designator
//    ;

//designator
//    :   '[' constantExpression ']'
//    ;

statement
    :   compoundStatement
    |   selectionStatement
    |   iterationStatement
    |   jumpStatement
    |   expressionStatement
    |   declaration
    |   translationUnit
    |   writeStatement
    ;

compoundStatement
    :   '{' blockItemList? '}'
    ;

blockItemList
    :   blockItem
    |   blockItemList blockItem
    ;

blockItem
    :   declaration
    |   statement
    ;

selectionStatement
    :   'if' '(' expression ')' statement ('else' statement)?
    ;

iterationStatement
    :   'while' '(' conditionalExpression ')' statement
    |   'for' '(' expression? ';' expression? ';' expression? ')' statement
    //|   'for' '(' declaration expression? ';' expression? ')' statement
    ;

jumpStatement
    :   'continue' ';'
    |   'break' ';'
    |   'return' expression? ';'
    ;

//表达式
expressionStatement
    :   expression? ';'
    ;

//单行表达式
expression
    :   assignmentExpression
    |   conditionalExpression
    |   expression ',' assignmentExpression
    ;

compilationUnit
    :   translationUnit? EOF
    ;

translationUnit
    :   externalDeclaration
    |   translationUnit externalDeclaration
    ;

externalDeclaration
    :   functionDefinition
    |   declaration
    |   ';' // stray ;
    ;

functionDefinition
    :   declarationSpecifier declarator compoundStatement
    ;

declarationList
    :   declaration
    |   declarationList declaration
    ;

typeSpecifier
    :   'void'
    |   'char'
    |   'short'
    |   'int'
    |   'long'
    |   'float'
    |   'double'
    ;

typeName
    :   specifierQualifierList
    ;
specifierQualifierList
    :   typeSpecifier
    ;




Zero
    :   [0]
    ;

Constant
    :   IntegerConstant
    |   FloatingConstant
    ;

fragment
IntegerConstant
    :   DecimalConstant
    ;

fragment
FloatingConstant
    :   DecimalFloatingConstant
    ;

fragment
DecimalFloatingConstant
    :   FractionalConstant
    ;

fragment
FractionalConstant
    :   DigitSequence? '.' DigitSequence
    |   DigitSequence '.'
    ;

fragment
DigitSequence
    :   Digit+
    ;

fragment
DecimalConstant
    :   NonzeroDigit Digit*
    ;

fragment
Digit
    :   [0-9]
    ;

fragment
NonzeroDigit
    :   [1-9]
    ;


Intconstant : [1-9]([0-9])*
            | '0' ('x'|'X') [0-9a-fA-F]+
            | '0'
            ;

Doubleconstant : '0'('.'([0-9])*)
               | [1-9]([0-9])*('.'([0-9])*)?
               | '0' ('x'|'X') [0-9a-fA-F]+
               ;
True : 'true';
False : 'false';

WS : [ \t]+ -> skip;

LeftParen : '(';
RightParen : ')';
LeftBracket : '[';
RightBracket : ']';
LeftBrace : '{';
RightBrace : '}';

Less : '<';
LessEqual : '<=';
Greater : '>';
GreaterEqual : '>=';
LeftShift : '<<';
RightShift : '>>';

Plus : '+';
PlusPlus : '++';
Minus : '-';
MinusMinus : '--';
Star : '*';
Div : '/';
Mod : '%';

And : '&';
Or : '|';
AndAnd : '&&';
OrOr : '||';
Caret : '^';
Not : '!';
Tilde : '~';

Question : '?';
Colon : ':';
Semi : ';';
Comma : ',';

Assign : '=';
StarAssign : '*=';
DivAssign : '/=';
ModAssign : '%=';
PlusAssign : '+=';
MinusAssign : '-=';
LeftShiftAssign : '<<=';
RightShiftAssign : '>>=';
AndAssign : '&=';
XorAssign : '^=';
OrAssign : '|=';

Equal : '==';
NotEqual : '!=';

Arrow : '->';
Dot : '.';

Write : 'write';

If : 'if';
Else : 'else';
While : 'while';
For : 'for';
Break : 'break';

Double : 'double';
Int : 'int';
Long : 'long';
Short : 'short';
Float : 'float';
Char : 'char';
Bool : 'bool';
Void : 'void';

Type : 'int'
     | 'double'
     ;


Newline
    :   (   '\r' '\n'?
        |   '\n'
        )
        -> skip
    ;

BlockComment
    :   '/*' .*? '*/'
        -> skip
    ;

LineComment
    :   '//' ~[\r\n]*
        -> skip
    ;

StringLiteral : '"' .*? '"';

Identifier : [a-zA-Z]+ ( [a-zA-Z] | [0-9] | '_' ([a-zA-Z]|[0-9])+ )*;

